/*
Copyright (c) 2007
Daniel Yang (daniel.yang.zhenyu at gmail.com)
Zh Su
All rights reserved.
Thanks to EarthPlayer.com and Silver.


Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
    Redistributions of source code must retain the above copyright notice,
    this list of conditions and the following disclaimer.
    Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
    Neither the name of Stamen Design, Look or Feel, nor the names of its
    contributors may be used to endorse or promote products derived from
    this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package cn.funcat.map{

	import cn.funcat.map.layer.EdsMapLayer;
	import cn.funcat.map.layer.IMapControl;
	import cn.funcat.map.layer.LayerBase;
	import cn.funcat.util.MapCursor;
	
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import mx.core.UIComponent;
	import mx.effects.Move;
	import mx.events.ResizeEvent;
	
	
	/**
	 * 主要的地图对象.
	 * 
	 * 本来支持多层的,现在直接使用EDSMapLayer.
	 * 建议改成多层, 这样其他层就可以做POI的Overlay了.
	 * @author daniel
	 * 
	 */	
	public class FCMap extends UIComponent implements IMapControl{
		
		private var _layerHolder:UIComponent;
		
		/**
		 * 可视范围的中心点
		 */  
		private var _centerPoint:Point;
		/**
		 * 可视范围
		 */ 
		private var _viewRect:Rectangle;
		
		/**
		 * 缩放
		 */		
		private var _zoomLevel:Number = 4;
		
		/**
		 * 为了计算offset x y
		 */		
		private var _lastX:Number;
		private var _lastY:Number;
		private var _mouseDown:Boolean;
		
		private var el:EdsMapLayer;	
		
		public function FCMap(){
			super();
			this.doubleClickEnabled = true;
			this.addEventListener(MouseEvent.MOUSE_DOWN, this.onMouseDown);
			this.addEventListener(MouseEvent.MOUSE_UP, this.onMouseUp);
			this.addEventListener(MouseEvent.ROLL_OUT, this.onMouseUp);	
			this.addEventListener(ResizeEvent.RESIZE, this.onMapResized);
			this.addEventListener(MouseEvent.DOUBLE_CLICK, this.onDbClick);
			this.addEventListener(MouseEvent.CLICK, onMapClick);
			//this.addEventListener(MouseEvent.MOUSE_WHEEL, this.onMouseWheel);
			el = new EdsMapLayer();
			
			_layerHolder = new UIComponent();
			this.addLayer(el);
			
			this.addChild(_layerHolder);
			
			_viewRect = new Rectangle(0, 0, this.width, this.height);
			_centerPoint = new Point();
		}	
		
		private function onMouseWheel(evt:MouseEvent):void{
			trace(evt.delta);
		}
		
		private function onMapClick(evt:MouseEvent):void{
			/* var p:Point = map2Global(new Point(evt.stageX, evt.stageY));*/	
		}
		
		/**
		 *  发生resize
		 * @param evt
		 * 
		 */		
		private function onMapResized(evt:ResizeEvent):void{
			this.centerPoint = new Point(width/2 - _layerHolder.x, height/2 - _layerHolder.y);
		 	this._viewRect.width = this.width;
			this._viewRect.height = this.height;
			this._viewRect.x = this._centerPoint.x - this.width/2;
			this._viewRect.y = this._centerPoint.y - this.height/2;
		}
		
		/**
		 * 双击
		 * @param evt
		 * 
		 */		
		private function onDbClick(evt:MouseEvent):void{
			moveMapBy(this.width/2-evt.stageX, this.height/2 - evt.stageY, true);
			this._mouseDown = false;
		}

		/**
		 *  换算
		 * @param p 界面上一点
		 * @return 全局
		 * 
		 */				
		public function map2Global(p:Point):Point{
			var r:Point = new Point(p.x + this._viewRect.x, p.y + this._viewRect.y);
			r.x = r.x * Math.pow(2, this._zoomLevel-1);
			r.y = r.y * Math.pow(2, this._zoomLevel-1);
			return r;
		}

		/**
		 *  换算
		 * @param p 全局一点
		 * @return 界面上一点
		 * 
		 */				
		public function global2Map(p:Point):Point{
			var r:Point = new Point(p.x - this._viewRect.x, p.y - this._viewRect.y);
			r.x = r.x / Math.pow(2, this._zoomLevel-1);
			r.y = r.y / Math.pow(2, this._zoomLevel-1);
			return r;
		}
		
		/**
		 * 可视范围发生改变
		 * 
		 */		
		private function changeViewRect():void{
			//应该改变所有的层, 这里直接使用了.
			el.changeViewRect(this._viewRect, this._zoomLevel);
		}
		
		/**
		 *  可视范围的中心点
		 * @return 
		 * 
		 */		
		public function get centerPoint():Point{
			return this._centerPoint;
		}
		
		public function set centerPoint(p:Point):void{
			this._centerPoint = p;
			this._layerHolder.x = (this.width/2-p.x);
			this._layerHolder.y = (this.height/2-p.y);
			
			this._viewRect.x = p.x - this.width/2;
			this._viewRect.y = p.y - this.height/2;
		
			this.changeViewRect();	
		}
	
		/**
		 * 
		 * @param evt
		 * 
		 */		
		private function onMouseDown(evt:MouseEvent):void{
			MapCursor.changeCursor(MapCursor.mapMoveCursor, -6, -6);
			_layerHolder.startDrag();
			
			_lastX = this._layerHolder.x;
			_lastY = this._layerHolder.y;
			_mouseDown = true;
		}
		
		/**
		 * 鼠标释放
		 * @param evt
		 * 
		 */		
		private function onMouseUp(evt:MouseEvent):void{
			if(!this._mouseDown) return;
			
			MapCursor.changeCursor(null, 0, 0);
			_layerHolder.stopDrag();	

			var offsetX:Number = _layerHolder.x - _lastX;
			var offsetY:Number = _layerHolder.y - _lastY;

			
			//如果有了移动
			if((offsetX != 0) || (offsetY != 0)){

				this._centerPoint.offset(-offsetX, -offsetY);

				this._viewRect.offset(-offsetX, -offsetY);
				
				this.changeViewRect();
				_mouseDown = false;
			}
		}
		
		public function set zoomLevel(level:Number):void{
			if(this._zoomLevel == level) return;

			var z:Number = Math.pow(2, (_zoomLevel-level));
			this._zoomLevel = level;

			var p:Point = new Point(this._centerPoint.x * z, this._centerPoint.y * z);
			this.centerPoint = p;
		}
		
		public function get zoomLevel():Number{
			return this._zoomLevel;
		}
		
		/**
		 * 
		 * @param _x
		 * @param _y
		 * @param ani
		 * 
		 */		
		public function moveMapBy(_x:Number, _y:Number, ani:Boolean):void{
			var p:Point = new Point(this._centerPoint.x-_x, this._centerPoint.y-_y);
			this._centerPoint = p;
			if(ani){
				var mv:Move = new Move(this._layerHolder);
				mv.xTo = this.width/2-p.x;
				mv.yTo = this.height/2-p.y;
				mv.play();
			}else{
				_layerHolder.x = this.width/2-p.x;
				_layerHolder.y =this.height/2-p.y;
			}
			
			this._viewRect.x = p.x - this.width/2;
			this._viewRect.y = p.y - this.height/2;
		
			this.changeViewRect();
		}
		
		/**
		 * 不再开放Layer
		 */ 
		private function addLayer(layer:LayerBase):void{
			_layerHolder.addChild(layer);
		}
		
		public function show3DMap():void{
			el.show3DMap();
		}
		
		public function show2DMap():void{
			el.show2DMap();
		}

		/**
		 * 转到地图的某一点
		 * @param p
		 * 统一的坐标
		 */		
		public function gotoMap(p:Point):void{
			p.x = p.x / Math.pow(2, this._zoomLevel-1);
			p.y = p.y / Math.pow(2, this._zoomLevel-1);
			
			this.centerPoint = p;
		}
		/**
		 * 中心点不会改变
		 */ 
		public function zoomMap(level:Number):void{
			this.zoomLevel = level;
		}	
	}

}